<?php

namespace app\common\model;

use app\admin\model\user\Withdraw;
use app\api\model\Stat;
use app\api\model\UserConsumeLog;
use app\api\model\UserUpgradeLog;
use app\shopapi\model\Shop;
use app\shopapi\model\ShopUser;
use think\Db;
use think\Model;

/**
 * 会员模型
 */
class User extends Model
{

    // 开启自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';
    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    // 追加属性
    protected $append = [
        'url',
        'jointime_text'
    ];

    /**
     * 获取个人URL
     * @param string $value
     * @param array  $data
     * @return string
     */
    public function getUrlAttr($value, $data)
    {
        return "/u/" . $data['id'];
    }

    /**
     * 获取头像
     * @param string $value
     * @param array  $data
     * @return string
     */
    public function getAvatarAttr($value, $data)
    {
        if (!$value) {
            //如果不需要启用首字母头像，请使用
            //$value = '/assets/img/avatar.png';
            $value = letter_avatar($data['nickname']);
        }
        return $value;
    }

    public function getJointimeTextAttr($value, $data)
    {
        $value = $value ? $value : ($data['jointime'] ?? "");
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    /**
     * 获取会员的组别
     */
    public function getGroupAttr($value, $data)
    {
        return UserGroup::get($data['group_id']);
    }

    /**
     * 获取验证字段数组值
     * @param string $value
     * @param array  $data
     * @return  object
     */
    public function getVerificationAttr($value, $data)
    {
        $value = array_filter((array)json_decode($value, true));
        $value = array_merge(['email' => 0, 'mobile' => 0], $value);
        return (object)$value;
    }

    /**
     * 设置验证字段
     * @param mixed $value
     * @return string
     */
    public function setVerificationAttr($value)
    {
        $value = is_object($value) || is_array($value) ? json_encode($value) : $value;
        return $value;
    }

    /**
     * 变更会员余额
     * @param int    $money   余额
     * @param int    $user_id 会员ID
     * @param string $memo    备注
     */
    public static function money($money, $user_id, $memo,$type=0)
    {
        Db::startTrans();
        try {
            $user = self::lock(true)->find($user_id);
            if ($user && $money != 0) {
                $before = $user->money;
                //$after = $user->money + $money;
                $after = function_exists('bcadd') ? bcadd($user->money, $money, 2) : $user->money + $money;
                if ($money>0){
                    $total_money =  bcadd($user->money, $money, 2);
                } else {
                    $total_money = $user->total_money;
                }
                //更新会员信息
                $user->save(['money' => $after,'total_money'=>$total_money]);
                //写入日志
                MoneyLog::create(['user_id' => $user_id, 'money' => $money, 'before' => $before, 'after' => $after, 'memo' => $memo, 'type' => $type]);
            }
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
        }
    }


    /**
     * 变更会员积分
     * @param int    $score   积分
     * @param int    $user_id 会员ID
     * @param string $memo    备注
     */
    public static function score($score, $user_id, $memo)
    {
        Db::startTrans();
        try {
            $user = self::lock(true)->find($user_id);
            if ($user && $score != 0) {
                $before = $user->score;
                $after = $user->score + $score;
                $level = self::nextlevel($after);
                //更新会员信息
                $user->save(['score' => $after, 'level' => $level]);
                //写入日志
                ScoreLog::create(['user_id' => $user_id, 'score' => $score, 'before' => $before, 'after' => $after, 'memo' => $memo]);
            }
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
        }
    }

    /**
     * 根据积分获取等级
     * @param int $score 积分
     * @return int
     */
    public static function nextlevel($score = 0)
    {
        $lv = array(1 => 0, 2 => 30, 3 => 100, 4 => 500, 5 => 1000, 6 => 2000, 7 => 3000, 8 => 5000, 9 => 8000, 10 => 10000);
        $level = 1;
        foreach ($lv as $key => $value) {
            if ($score >= $value) {
                $level = $key;
            }
        }
        return $level;
    }

    //获取直推人数列表
    public function getFirstTeamList($user_id)
    {
        //$user = User::get($user_id);
        //$parent = User::get($user->parent_id);
        $list = User::where(['parent_id'=>$user_id])
            ->field('id,nickname,avatar,jointime,createtime,parent_id')
            ->order('createtime desc')
            ->paginate(10, false, ['query' => request()->get()]);

        /*$data = [
            'parent_mobile'=>$parent?$parent->mobile:'',
            'list'=>$list,
        ];*/

        return $list;
    }

    //获取直推人数
    //type 0是累计直推,1今日直推,2昨日直推,3本月直推
    public function getFirstTeamCount($user_id,$type=0)
    {
        // 当天开始时间戳
        $todayStart = strtotime("today");
        // 当天结束时间戳
        $todayEnd = strtotime("tomorrow") - 1;

        // 昨天开始时间戳
        $yesterdayStart = strtotime("yesterday");
        // 昨天结束时间戳
        $yesterdayEnd = strtotime("today") - 1;

        // 当月开始时间戳
        $monthStart = strtotime(date('Y-m-01 00:00:00'));
        // 当月结束时间戳
        $monthEnd = strtotime(date('Y-m-t 23:59:59'));

        $where = ['parent_id'=>$user_id];
        if ($type==1){
            $where['createtime'] = ['between', [$todayStart, $todayEnd]];
        } elseif ($type==2){
            $where['createtime'] = ['between', [$yesterdayStart, $yesterdayEnd]];
        } elseif ($type==3){
            $where['createtime'] = ['between', [$monthStart, $monthEnd]];
        }

        $count = User::where($where)->count();

        return $count;
    }

    //获取团队人数
    public function getTeamCount($user_id)
    {
        $count = $this->getChildList($user_id);
        return count($count);
    }

    //获取团队v2人数
    public function getV2TeamCount($user_id)
    {
        $list = $this->getChildV2List($user_id);
        return count($list);
    }

    //获取团队购买699人数
    public function get699TeamCount($user_id)
    {
        $count = $this->getChild699List($user_id);
        return count($count);
    }

    //获取推荐有效店铺数
    public function getValidShopCount($user_id)
    {
        $count = ShopUser::alias('u')
            ->join('shop s','u.id = s.shop_id')
            ->where(['u.recommender_id'=>$user_id])
            ->where('s.fans_num','>',500)
            ->count();
        return $count;
    }

    //获取用户+所有v2下级累计90天提现金额
    public function getV2WithdrawMoney($user_id)
    {
        $user_id_arr = $this->getChildV2List($user_id);
        $withdraw_money = Withdraw::where('user_id','in',$user_id_arr)
            ->where('transfertime', 'between time', [time()-90*86400, time()])
            ->where(['status'=>'successed','transfertime'=>['>',0]])
            ->sum('money');
        return $withdraw_money;
    }

    //递归获取用户所有下级
    public function getChildList($user_id)
    {
        //第一次调用时初始化
        static $arr=array();
        //通过邀请码查询当前邀请码下级用户
        $data = User::where(['parent_id'=>$user_id])
            ->field('id')
            ->select();
        //遍历获取信息，调用当前方法直至没有下级用户
        foreach ($data as $key => $value) {
            $arr[] = $value;
            $this->getChildList($value['id']);
        }
        return $arr;
    }

    //递归获取用户所有下级V2
    public function getChildV2List($user_id)
    {
        //第一次调用时初始化
        static $arr=array();
        //通过邀请码查询当前邀请码下级用户
        $data = User::where(['parent_id'=>$user_id,'level'=>2])
            ->field('id')
            ->select();
        //遍历获取信息，调用当前方法直至没有下级用户
        foreach ($data as $key => $value) {
            $withdraw_price = Withdraw::where('user_id','=',$value['id'])
                ->where(['status'=>'successed','transfertime'=>['>',0]])
                ->where('createtime', 'between time', [time()-90*86400, time()])
                ->sum('money');
            if ($withdraw_price>500){
                $arr[] = $value;
                $this->getChildList($value['id']);
            }

        }
        return $arr;
    }

    //递归获取用户所有下级购买699
    public function getChild699List($user_id)
    {
        //第一次调用时初始化
        static $arr=array();
        //通过邀请码查询当前邀请码下级用户
        $data = User::where(['parent_id'=>$user_id,'is_buy_699'=>1])
            ->field('id')
            ->select();
        //遍历获取信息，调用当前方法直至没有下级用户
        foreach ($data as $key => $value) {
            $arr[] = $value;
            $this->getChildList($value['id']);
        }
        return $arr;
    }


    //递归获取用户所有一星用户
    public function getChildOneStarList($user_id)
    {
        //第一次调用时初始化
        static $arr=array();
        //通过邀请码查询当前邀请码下级用户
        $data = User::where(['parent_id'=>$user_id,'level'=>3,'level_star'=>1])
            ->field('id')
            ->select();
        //遍历获取信息，调用当前方法直至没有下级用户
        foreach ($data as $key => $value) {
            $arr[] = $value;
            $this->getChildList($value['id']);
        }
        return $arr;
    }

    //递归获取用户所有二星用户
    public function getChildTwoStarList($user_id)
    {
        //第一次调用时初始化
        static $arr=array();
        //通过邀请码查询当前邀请码下级用户
        $data = User::where(['parent_id'=>$user_id,'level'=>3,'level_star'=>2])
            ->field('id')
            ->select();
        //遍历获取信息，调用当前方法直至没有下级用户
        foreach ($data as $key => $value) {
            $arr[] = $value;
            $this->getChildList($value['id']);
        }
        return $arr;
    }

    //递归获取用户所有三星用户
    public function getChildThreeStarList($user_id)
    {
        //第一次调用时初始化
        static $arr=array();
        //通过邀请码查询当前邀请码下级用户
        $data = User::where(['parent_id'=>$user_id,'level'=>3,'level_star'=>3])
            ->field('id')
            ->select();
        //遍历获取信息，调用当前方法直至没有下级用户
        foreach ($data as $key => $value) {
            $arr[] = $value;
            $this->getChildList($value['id']);
        }
        return $arr;
    }


    //检测用户升级
    public function upgrade($user_id)
    {

        $user = User::where(['id'=>$user_id])->find();
        if ($user) {
            $memo = '';
            //直推有效店铺数
            $stat_model = new Stat();

            $valid_shop_count = $stat_model->getValidShopCount($user_id);

            //团队推荐的有效店铺数
            $team_valid_shop_count = $stat_model->getTeamValidShopCount($user_id);


            //直邀有效V2人数
            $v2_list = User::alias('u')->where(['u.parent_id'=>$user_id,'u.level'=>2])
                ->field('id,parent_id,level')->select();
            $v2_count = 0;
            foreach ($v2_list as $k=>$v){
                $withdraw_price = Withdraw::where('user_id','=',$v['id'])
                    ->where(['status'=>'successed','transfertime'=>['>',0]])
                    ->where('createtime', 'between time', [time()-90*86400, time()])
                    ->sum('money');
                if ($withdraw_price>500){
                    $v2_count++;
                }
            }

            //直邀有效V3人数
            $v3_list = User::where(['parent_id'=>$user_id,'level'=>3])->field('id,parent_id,level')->select();
            $v3_count = 0;
            foreach ($v3_list as $k=>$v){
                $withdraw_price = Withdraw::where('user_id','=',$v['id'])
                    ->where(['status'=>'successed','transfertime'=>['>',0]])
                    ->where('createtime', 'between time', [time()-90*86400, time()])
                    ->sum('money');
                if ($withdraw_price>1500){
                    $v3_count++;
                }
            }

            //二级有效V3人数
            $child = User::where(['parent_id'=>$user_id])->column('id');
            $two_v3_list = User::where(['parent_id'=>['in',$child],'level'=>3])->select();
            $two_v3_count = 0;
            foreach ($two_v3_list as $k=>$v){
                $withdraw_price = Withdraw::where('user_id','=',$v['id'])
                    ->where(['status'=>'successed','transfertime'=>['>',0]])
                    ->where('createtime', 'between time', [time()-90*86400, time()])
                    ->sum('money');
                if ($withdraw_price>1500){
                    $two_v3_count++;
                }
            }

            //团队有效V2人数
            $indirect_v2_count = $this->getV2TeamCount($user_id);

            //自己以及V2近90天累积体现金额
            $v2_withdraw_money = $this->getV2WithdrawMoney($user_id);

            //自己累积提现金额
            $self_withdraw_money = Withdraw::where('user_id','=',$user_id)
                ->where(['status'=>'successed','transfertime'=>['>',0]])
                ->sum('money');



            //三星部门
            $three_star_v3_count = count($this->getChildThreeStarList($user_id));

            if ($user->level==1){
                //检测升级v2
                //升级方式 自购一单&&完成10道题
                if ($user->question_pass==1&&$user->is_buy==1){
                    $memo = '满足自购一单&&完成10道题升级为v2';
                    UserUpgradeLog::log($user_id,2,$memo);
                }

            } elseif ($user->level==2){
                //检测升级v3

                //升级方式一  升级方式 自己开发有效商铺大于20家&&自己直邀+间邀开发有效商铺大于50家
                if ($valid_shop_count>20&&$team_valid_shop_count>50){
                    $memo = '满足自己开发有效商铺大于20家&&自己直邀+间邀开发有效商铺大于50家为v3';
                    UserUpgradeLog::log($user_id,3,$memo);
                }

                //升级方式二  升级方式  直邀有效V2大于10人&&直邀+间邀有效V2大于20人&&自己以及V2近90天累积体现大于500元
                if ($v2_count>10&&$indirect_v2_count>20&&$v2_withdraw_money>500){
                    $memo = '满足直邀有效V2大于10人&&直邀+间邀有效V2大于20人&&自己以及V2近90天累积体现大于500元';
                    UserUpgradeLog::log($user_id,3,$memo);
                }
                //升级方式三


            } elseif ($user->level==3){
                //检测升级v4

                //升级方式一 升级方式 自己开发有效店铺大于100家&&自己直邀+间邀开发有效店铺大于2000家&&自己累积提现大于5000元
                if ($valid_shop_count>100&&$team_valid_shop_count>2000&&$self_withdraw_money>5000){
                    $memo = '满足 自己开发有效店铺大于100家&&自己直邀+间邀开发有效店铺大于2000家&&自己累积提现大于5000元升级为v4';
                }
                //升级方式二  升级方式 一级有效V3大于10人&&一级+二级有效V3大于20人&&自己提现大于5万元
                if ($v3_count>10&&$two_v3_count+$v3_count>20&&$self_withdraw_money>50000){
                    $memo = '满足 一级有效V3大于10人&&一级+二级有效V3大于20人&&自己提现大于5万元升级为v4';
                }

                //升级方式三  升级方式 自己开发有效店铺大于100家&&自己直邀+间邀开发有效店铺大于1000家&&一级有效V3大于10人&&自己累积提现大于5万元
                if ($valid_shop_count>100&&$team_valid_shop_count>1000&&$v3_count>10&&$self_withdraw_money>50000){
                    $memo = '满足 一级有效V3大于10人&&一级+二级有效V3大于20人&&自己提现大于5万元升级为v4';
                }
                //升级方式四  升级方式 达标2个三星福袋V3
                if ($three_star_v3_count>=2){
                    $memo = '满足 达标2个三星福袋V3升级为v4';
                }

                if ($memo)UserUpgradeLog::log($user_id,4,$memo);

            }

        }

    }


    //我的地推
    public function getGroundPromotionList($user_id,$sort,$level,$keyword,$user_level)
    {
        $user = User::get($user_id);

        $where = [];

        if ($user_level>0){
            $where['level'] = $user_level;
        }

        if(!empty($keyword)){
            $where['nickname|mobile'] = ['like',"%$keyword%"];
        }

        $field = 'id,nickname,avatar,mobile,level,createtime,jointime,parent_id';

        if ($level==1){
            $where['parent_id'] = $user_id;
        } else {
            $first_child = User::where(['parent_id'=>$user_id])->column('id');

            if ($first_child){
                if ($user->level>=3){
                    //v3查看所有人
                    $team_id = $this->getChildList($user_id);
                    $child = array_column($team_id,'id');
                } else {
                    $second_child = User::where('parent_id','in',$first_child)->column('id');
                    $child = $second_child;
                }
                if ($child){
                    $where['id'] = ['in',$child];
                } else {
                    $where['id'] = 0;
                }
            } else {
                $where['id'] = 0;
            }
        }
        //if ($sort==1){
        $order='createtime desc';
        //}

        $list = User::where($where)->field($field)->order($order)
            ->paginate(50, false, ['query' => request()->get()]);
        $stat_model = new Stat();
        $user_model = new \app\common\model\User();
        $user_consume_log_model = new UserConsumeLog();
        foreach ($list as $k=>$v){
            $list[$k]['recommend_shop_count'] = $stat_model->getShopCount($v['id']);

            $list[$k]['shop_turnover'] = $stat_model->getShopTurnover($v['id']);

            $list[$k]['shop_fans_count'] = $stat_model->getShopFansCount($v['id']);

            $list[$k]['total_recommend_count'] = $user_model->getFirstTeamCount($v['id'],0);

            $list[$k]['today_recommend_count'] = $user_model->getFirstTeamCount($v['id'],1);

            $list[$k]['month_recommend_count'] = $user_model->getFirstTeamCount($v['id'],3);

            $list[$k]['total_commission'] = $user_consume_log_model->forecastCommission($v['id'],0);

            $list[$k]['month_commission'] = $user_consume_log_model->forecastCommission($v['id'],3);

            $list[$k]['today_commission'] = $user_consume_log_model->forecastCommission($v['id'],1);

        }

        if ($sort>1){
            $list = $list->toArray();
        }
        switch ($sort) {
            case 2 :
                array_multisort(array_column($list['data'], 'recommend_shop_count'), SORT_DESC, $list['data']);
                break;
            case 3 :
                array_multisort(array_column($list['data'], 'shop_turnover'), SORT_DESC, $list['data']);
                break;
            case 4 :
                array_multisort(array_column($list['data'], 'today_commission'), SORT_DESC, $list['data']);
                break;
            case 5 :
                array_multisort(array_column($list['data'], 'month_commission'), SORT_DESC, $list['data']);
                break;
            case 6 :
                array_multisort(array_column($list['data'], 'total_commission'), SORT_DESC, $list['data']);
                break;
            case 7 :
                array_multisort(array_column($list['data'], 'today_recommend_count'), SORT_DESC, $list['data']);
                break;
            case 8 :
                array_multisort(array_column($list['data'], 'month_recommend_count'), SORT_DESC, $list['data']);
                break;
            case 9 :
                array_multisort(array_column($list['data'], 'total_recommend_count'), SORT_DESC, $list['data']);
                break;
        }

        $team_count_data = $this->getSecondaryTeamCount($user_id,$level);

        return [
            'team_count_data'=>[
                'total_team_count'=>$team_count_data['count'],
                'total_v1_team_count'=>$team_count_data['v1count'],
                'total_v2_team_count'=>$team_count_data['v2count'],
                'total_v3_team_count'=>$team_count_data['v3count'],
            ],
            'list'=>$list
        ];
    }
    public function oldgetGroundPromotionList($user_id,$sort,$level,$keyword,$user_level)
    {
        $user = User::get($user_id);
        $query = new User();
        $list=[];
        if ($user_level>0){
            $query->where('level','=',$user_level);
        }

        if ($keyword){
            $query->where('nickname|mobile', 'like', '%' . $keyword . '%');
        }

        $query->field('id,nickname,avatar,mobile,level,createtime,jointime,parent_id');
        if ($sort==1){
            $query->order('createtime desc');
        }

        if ($level==1){
            $query->where('parent_id','=',$user_id);
            //$query =  User::where(['parent_id'=>$user_id]);
        } else {
            $first_child = User::where(['parent_id'=>$user_id])->column('id');
            if ($first_child){
                if ($user->level>=3){
                    //v3查看所有人
                    $team_id = $this->getChildList($user_id);
                    $child = array_column($team_id,'id');

                } else {
                    $second_child = User::where('parent_id','in',$first_child)->column('id');
                    $child = array_merge($first_child,$second_child);
                }
                $query->where('id','in',$child);
            }
        }


        $list = $query->paginate(20, false, ['query' => request()->get()]);
        $stat_model = new Stat();
        $user_model = new \app\common\model\User();
        $user_consume_log_model = new UserConsumeLog();
        foreach ($list as $k=>$v){
            $list[$k]['recommend_shop_count'] = $stat_model->getShopCount($v['id']);

            $list[$k]['shop_turnover'] = $stat_model->getShopTurnover($v['id']);

            $list[$k]['shop_fans_count'] = $stat_model->getShopFansCount($v['id']);

            $list[$k]['total_recommend_count'] = $user_model->getFirstTeamCount($v['id'],0);

            $list[$k]['today_recommend_count'] = $user_model->getFirstTeamCount($v['id'],1);

            $list[$k]['month_recommend_count'] = $user_model->getFirstTeamCount($v['id'],3);

            $list[$k]['total_commission'] = $user_consume_log_model->forecastCommission($v['id'],0);

            $list[$k]['month_commission'] = $user_consume_log_model->forecastCommission($v['id'],3);

            $list[$k]['today_commission'] = $user_consume_log_model->forecastCommission($v['id'],1);

        }

        if ($sort>1){
            $list = $list->toArray();
        }
        switch ($sort) {
            case 2 :
                array_multisort(array_column($list['data'], 'recommend_shop_count'), SORT_DESC, $list['data']);
                break;
            case 3 :
                array_multisort(array_column($list['data'], 'shop_turnover'), SORT_DESC, $list['data']);
                break;
            case 4 :
                array_multisort(array_column($list['data'], 'today_commission'), SORT_DESC, $list['data']);
                break;
            case 5 :
                array_multisort(array_column($list['data'], 'month_commission'), SORT_DESC, $list['data']);
                break;
            case 6 :
                array_multisort(array_column($list['data'], 'total_commission'), SORT_DESC, $list['data']);
                break;
            case 7 :
                array_multisort(array_column($list['data'], 'today_recommend_count'), SORT_DESC, $list['data']);
                break;
            case 8 :
                array_multisort(array_column($list['data'], 'month_recommend_count'), SORT_DESC, $list['data']);
                break;
            case 9 :
                array_multisort(array_column($list['data'], 'total_recommend_count'), SORT_DESC, $list['data']);
                break;
        }


        $team_count_data = $this->getSecondaryTeamCount($user_id);

        return [
            'team_count_data'=>[
                'total_team_count'=>$team_count_data['count'],
                'total_v1_team_count'=>$team_count_data['v1count'],
                'total_v2_team_count'=>$team_count_data['v2count'],
                'total_v3_team_count'=>$team_count_data['v3count'],
            ],
            'list'=>$list
        ];
    }

    //获取用户的一级二级的所有人数以用户等级区分
    public function getSecondaryTeamCount($user_id,$level)
    {
        $first_child = User::where(['parent_id'=>$user_id])->column('id');
        if ($first_child){
            $second_child = User::where('parent_id','in',$first_child)->column('id');
            if ($level==1){
                $child = $first_child;
            } else {
                $child = $second_child;
            }
            //$child = array_merge($first_child,$second_child);

            $count = User::where('id','in',$child)->count();

            $v1count = User::where('id','in',$child)->where('level',1)->count();

            $v2count = User::where('id','in',$child)->where('level',2)->count();

            $v3count = User::where('id','in',$child)->where('level',3)->count();
        } else {
            $count = 0;
            $v1count = 0;
            $v2count = 0;
            $v3count = 0;
        }


        return [
            'count'=>$count,
            'v1count'=>$v1count,
            'v2count'=>$v2count,
            'v3count'=>$v3count
        ];

    }


}
